package dipl.visualizer.graphics;

import dipl.algorithm.math.fp.primitive.Matrix3x3f;

/**
 * Operations on 3x3 matrices
 */
public class Matrix3x3Ops {

	//
	// PUBLIC METHODS
	//

	/**
	 * Inverts given matrix m. Throws an exception if m is not invertible.
	 * @param m
	 * @return
	 * @throws Exception
	 */
	public static Matrix3x3f invert( /*out*/ Matrix3x3f m ) throws Exception {
		double det = m.Determinant();
		if( det == 0.0 )
			throw new Exception( "Matrix is not invertible!" );
		det = 1.0/det;

		double a11 = m.m[0][0], a12 = m.m[0][1], a13 = m.m[0][2];
		double a21 = m.m[1][0], a22 = m.m[1][1], a23 = m.m[1][2];
		double a31 = m.m[2][0], a32 = m.m[2][1], a33 = m.m[2][2];

		m.m[0][0] = det*(a33*a22-a32*a23);  m.m[0][1] = -det*(a33*a12-a32*a13); m.m[0][2] = det*(a23*a12-a22*a13);
		m.m[1][0] = -det*(a33*a21-a31*a23); m.m[1][1] = det*(a33*a11-a31*a13);  m.m[1][2] = -det*(a23*a11-a21*a13);
		m.m[2][0] = det*(a32*a21-a31*a22);  m.m[2][1] = -det*(a32*a11-a31*a12); m.m[2][2] = det*(a22*a11-a21*a12);
		return m;
	}

	/**
	 * Calculates a*b. The result is returned
	 * @param a
	 * @param b
	 * @return
	 */
	public static Matrix3x3f multiply( Matrix3x3f a, Matrix3x3f b ) {
		Matrix3x3f prod = new Matrix3x3f();
		for( int i=0; i<=2; i++ ) {
			for( int j=0; j<=2; j++ ) {
				prod.m[i][j] = 0.0;
				for( int k=0; k<=2; k++ ) {
					prod.m[i][j]+=a.m[i][k]*b.m[k][j];
				}
			}
		}
		return prod;
	}
}
